package top.wbhzx.wangpan.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import top.wbhzx.wangpan.auth.AuthFilter;
import top.wbhzx.wangpan.auth.AuthService;
import top.wbhzx.wangpan.auth.UserInfo;
import top.wbhzx.wangpan.config.Constant;
import top.wbhzx.wangpan.mapper.AdminMapper;
import top.wbhzx.wangpan.mapper.DirMapper;
import top.wbhzx.wangpan.mapper.FileMapper;
import top.wbhzx.wangpan.entity.Admin;
import top.wbhzx.wangpan.entity.AttrUtil;
import top.wbhzx.wangpan.entity.Dir;
import top.wbhzx.wangpan.entity.FD;
import top.wbhzx.wangpan.entity.File;
import top.wbhzx.wangpan.entity.User;
import top.wbhzx.wangpan.service.UserService;
import top.wbhzx.wangpan.util.HttpData;
import top.wbhzx.wangpan.util.ServiceResult;

/**
 * @author wangbohui
 */
@RestController
@RequestMapping(value="/user")
public class UserController {
	private static final Logger logger = LoggerFactory.getLogger(UserController.class);
	/**
	 * 用户服务
	 */
	@Autowired
	private UserService userService;
	/**
	 * 管理员服务
	 */
	@Autowired
	private AdminMapper AdminMapper;
	/**
	 * 文件服务
	 */
	@Autowired
	private FileMapper fileMapper;
	/**
	 * 文件夹服务
	 */
	@Autowired
	private DirMapper dirMapper;
	/**
	 * 权限服务
	 */
	@Autowired
	private AuthService authService;
	
	/**
	 * 注册接口
	 * @param username
	 * @param password
	 * @param phone
	 * @return 
	 */
	@PostMapping(value="/register.json")
	public ServiceResult userRegister(@RequestParam String username, @RequestParam String password, @RequestParam String phone) {
		User user = new User();
		user.setUsername(username);
		user.setPassword(password);
		user.setPhone(phone);

		User qUser = new User();
		qUser.setPhone(user.getPhone());
		//验证手机或邮箱的唯一性
		try {
			if(userService.selListByPo(qUser).size() > 0) {
				return ServiceResult.success(null,"手机号已被注册");
			}
		} catch (Exception e) {
			logger.error("用户注册:" + "查询手机号唯一性", e);
			return ServiceResult.failure("查询手机号唯一性异常");
		}
		
		//验证账号唯一性
		qUser.setUsername(user.getUsername());
		qUser.setPhone(null);
		try {
			if(userService.selListByPo(qUser).size() > 0) {
				return ServiceResult.failure("账号已注册");
			}
		} catch (Exception e) {
			logger.error("用户注册:" + "查询账号唯一性", e);
			return ServiceResult.failure("查询账号唯一性异常");
		}
		
		//初始化户用数据
		user.setRegisterTime(System.currentTimeMillis());
		user.setState(1);
		user.setRole(1);
		try {
			if(userService.addOne(user) > 0) {
				//查询用户id
				Integer newId = userService.selListByPo(new User(user.getUsername(),null,null)).get(0).getId();
				//创建基础文件夹
				Dir dir = new Dir();
				dir.setDirName("我的文件");
				dir.setDirParentId(1);
				dir.setDirPath("/root/"+user.getUsername());
				dir.setUserId(newId);
				dirMapper.insert(dir);
				return ServiceResult.success(user.getUsername(), "注册成功");
			}
		} catch (Exception e) {
			logger.error("用户注册:" + "插入数据", e);
			return ServiceResult.failure("插入数据异常");
		}
		return ServiceResult.failure("数据新增失败");
	}

	/**
	 * 登录接口
	 * @param username
	 * @param password
	 * @return
	 */
	@PostMapping(value = "/login.json")
	public ServiceResult login(@RequestParam String username, @RequestParam String password) {
		User user = new User();
		user.setUsername(username);
		user.setPassword(password);
		
		List<User> userlist = null;
		try {
			userlist = userService.selListByPo(user);	
		} catch (Exception e) {
			logger.error("管理员登录时:" + "通过账号密码查询用户", e);
			return ServiceResult.failure(Constant.ERROR_RETURN_CODE,"登录失败");
		}

		if(userlist.size() <= 0) {
			return ServiceResult.failure("账号验证未通过");
		}
		
		if(userlist.size() > 0 && userlist.get(0).getState() != 0) {
			User tempUser = userlist.get(0);

			// 成功之后Redis缓存用户信息
			UserInfo userInfo = new UserInfo();
			userInfo.setPhoneNo(tempUser.getPhone());
			userInfo.setUserId(tempUser.getId());
			userInfo.setEmail(tempUser.getEmail());
			String token = authService.createToken(userInfo.getUserId().toString(), userInfo);

			tempUser.setSeesion(token);

			return ServiceResult.success(tempUser, "登录成功");
		}else{
			return ServiceResult.failure("账号已停用");
		}

	}

	/**
	 * 管理员登录
	 * @param username
	 * @param password
	 * @return
	 */
	@PostMapping(value = "/adminLogin.json")
	public ServiceResult login2(@RequestParam String username, @RequestParam String password) {
		Admin admin = new Admin();
		admin.setAdminName(username);
		admin.setPassword(password);

		List<Admin> adminlist = null;
		try {
			adminlist = AdminMapper.selectListByPo(admin);
		} catch (Exception e) {
			logger.error("管理员登录时:" + "通过账号密码查询用户失败", e);
			return ServiceResult.failure("通过账号密码查询用户失败");
		}

		if(adminlist.size() <= 0) {
			return ServiceResult.failure("登录验证失败");
		}

		if(adminlist.size() > 0 && adminlist.get(0).getState() != 0) {
			return ServiceResult.success(adminlist.get(0), "登录成功");
		}else{
			return ServiceResult.failure("账号已停用");
		}
	}

	/**
	 * 增加实体
	 * @param map
	 * @return
	 */
	@PostMapping(value = "/add.json")
	public ServiceResult add(@RequestBody HashMap<String,HashMap<String, Object>> map) {
		//判断所操作的类
		Integer key = (Integer)map.get("info").get("objCode");
		
		//准备实体类
		Object object = null; 
		switch (key) {
		case 1:
			object = new User();
			break;
		case 2:
			object = new Admin();
			break;
		case 3:
			object = new File();
			break;
		case 4:
			object = new Dir();
			break;
		default:
			logger.error("增加实体类:" + "objCode有误");
			return ServiceResult.failure("objCode有误");
		}
		
		//为实体类设值
		try {
			AttrUtil.setAttributes(object, map.get("obj"));
		} catch (IllegalAccessException e1) {
			logger.error("增加实体类:" + "参数有误", e1);
			return ServiceResult.failure("参数有误");
		} catch (NoSuchFieldException e1) {
			logger.error("增加实体类:" + "参数有误", e1);
			return ServiceResult.failure("参数有误");
		}

		int count;
		try {
			switch (key) {
				case 1:
					User u = (User)object;
					u.setRegisterTime(System.currentTimeMillis());
					count = userService.addOne(u);
					if(count > 0) {
						Integer uId = userService.selListByPo(new User(u.getUsername(),null,null)).get(0).getId();
						Dir dir = new Dir();
						dir.setDirName("我的文件");
						dir.setDirParentId(1);
						dir.setDirPath("/root/"+u.getUsername());
						dir.setUserId(uId);
						dirMapper.insert(dir);
					}
					break;
				case 2:
					Admin ad = (Admin)object;
					ad.setRegisterTime(System.currentTimeMillis());
					count = AdminMapper.insertSelective((Admin)object);
					break;
				case 3:
					File f = (File)object;
					f.setFileUploadTime(System.currentTimeMillis());
					count = fileMapper.insertSelective((File)object);
					break;
				case 4:
					count = dirMapper.insertSelective((Dir)object);
					break;
				default:
					logger.error("增加实体类:" + "objCode有误");
					return ServiceResult.failure("objCode有误");
			}
		} catch (Exception e) {
			logger.error("增加实体:" + "初始化数据时,可能参数不足", e);
			return ServiceResult.failure("初始化数据时,可能参数不足");
		}
		if(count >= 0) {
			return ServiceResult.success(count,"增加成功");
		} else {
			return ServiceResult.failure("增加数据异常");

		}
	}

	/**
	 * 删除实体
	 * @param map
	 * @return
	 */
	@RequestMapping(value = "/remove.json")
	public ServiceResult remove(@RequestBody HashMap<String,HashMap<String, Object>> map) {
		//判断所操作的类
		Integer key = (Integer)map.get("info").get("objCode");
		
		Integer[] ids = JSONArray.toJavaObject((JSON)map.get("obj").get("ids"), Integer[].class);
		
		//执行删除
		try {
			int delCount = 0;
			switch (key) {
			case 1:
				delCount =  userService.removeListById(ids);
				break;
			case 2:
				delCount = AdminMapper.deleteListByPrimaryKey(ids);
				break;
			case 3:
				delCount = fileMapper.deleteListByPrimaryKey(ids);
				break;
			case 4:
				delCount = dirMapper.deleteListByPrimaryKey(ids);
				break;
			default:
				return ServiceResult.failure("objCode有误");
			}
			return ServiceResult.success(delCount, "删除成功");
		} catch (Exception e) {
			logger.error("删除实体:" + "删除数据时失败", e);
			return ServiceResult.failure("删除数据异常");
		}
	}

	/**
	 * 更改实体
	 * @param map
	 * @return
	 */
	@PostMapping(value = "/update.json")
	public ServiceResult update(@RequestBody HashMap<String,HashMap<String, Object>> map) {
		//判断所操作的类
		Integer key = (Integer)map.get("info").get("objCode");
		
		//准备实体类
		Object object = null; 
		switch (key) {
		case 1:
			object = new User();
			break;
		case 2:
			object = new Admin();
			break;
		case 3:
			object = new File();
			break;
		case 4:
			object = new Dir();
			break;
		default:
			return ServiceResult.failure("objectCode有误");
		}
		
		//为实体类设值
		String tempStr = "";
		try {
			AttrUtil.setAttributes(object, map.get("obj"));
		} catch (IllegalArgumentException e1) {
			logger.error("更新实体:" + "参数有误", e1);
			tempStr = "参数有误";
		} catch (IllegalAccessException e1) {
			logger.error("更新实体:" + "参数有误", e1);
			tempStr = "参数有误";
		} catch (NoSuchFieldException e1) {
			logger.error("更新实体:" + "参数有误", e1);
			tempStr = "参数有误";
		} catch (SecurityException e1) {
			logger.error("更新实体:" + "参数有误", e1);
			tempStr = "参数有误";
		}
		
		if("参数有误".equals(tempStr)) {
			return ServiceResult.failure(Constant.ERROR_RETURN_CODE, "参数有误", Constant.ERROR_RETURN_MESSAGE);
		}
		
		try {
			int updateCount = 0;
			switch (key) {
			case 1:
				updateCount = userService.modifyOnById((User)object);
				break;
			case 2:
				updateCount = AdminMapper.updateByPrimaryKeySelective((Admin)object);
				break;
			case 3:
				updateCount = fileMapper.updateByPrimaryKeySelective((File)object);
				break;
			case 4:
				updateCount = dirMapper.updateByPrimaryKeySelective((Dir)object);
				break;
			default:
				break;
			}
			return ServiceResult.success(updateCount, "更新成功");
		} catch (Exception e) {
			logger.error("更新实体:" + "更新数据时出错", e);
			return ServiceResult.failure(Constant.ERROR_RETURN_CODE, "数据更新异常", Constant.ERROR_RETURN_MESSAGE);
		}
		
	}
	
	@RequestMapping(value = "/query.json")
	public ServiceResult query(@RequestBody HashMap<String,HashMap<String, Object>> map, HttpServletResponse response) {
		//判断所操作的类
		Integer key = (Integer)map.get("info").get("objCode");
		
		//准备实体类
		Object object = null; 
		switch (key) {
		case 1:
			object = new User();
			break;
		case 2:
			object = new Admin();
			break;
		case 3:
			object = new File();
			break;
		case 4:
			object = new Dir();
			break;
		default:
			return ServiceResult.failure(Constant.ERROR_RETURN_CODE,"objectCode有误", Constant.ERROR_RETURN_MESSAGE);
		}

		//为实体类设值
		if(map.get("obj") != null) {
			try {
				AttrUtil.setAttributes(object, map.get("obj"));
			} catch (IllegalArgumentException e1) {
				logger.error("查询实体:" + "数据绑定时出错", e1);
				return ServiceResult.failure(Constant.ERROR_RETURN_CODE, "数据绑定时出错", Constant.ERROR_RETURN_MESSAGE);
			} catch (IllegalAccessException e1) {
				logger.error("查询实体:" + "数据绑定时出错", e1);
				return ServiceResult.failure(Constant.ERROR_RETURN_CODE, "数据绑定时出错", Constant.ERROR_RETURN_MESSAGE);
			} catch (NoSuchFieldException e1) {
				logger.error("查询实体:" + "数据绑定时出错", e1);
				return ServiceResult.failure(Constant.ERROR_RETURN_CODE, "数据绑定时出错", Constant.ERROR_RETURN_MESSAGE);
			} catch (SecurityException e1) {
				logger.error("查询实体:" + "数据绑定时出错", e1);
				return ServiceResult.failure(Constant.ERROR_RETURN_CODE, "数据绑定时出错", Constant.ERROR_RETURN_MESSAGE);
			}
		}
		
		try {
			switch (key) {
			case 1:
				return ServiceResult.success(userService.selListByPo((User)object), "查询实体成功");
			case 2:
				return ServiceResult.success(AdminMapper.selectListByPo((Admin)object), "查询实体成功");
			case 3:
				return ServiceResult.success(fileMapper.selectListByPo((File)object), "查询实体成功");
			case 4:
				return ServiceResult.success(dirMapper.selectListByPo((Dir)object), "查询实体成功");
			default:
				return ServiceResult.failure(Constant.ERROR_RETURN_CODE, "objectCode有误", Constant.ERROR_RETURN_MESSAGE);
			}

		} catch (Exception e) {
			logger.error("查询实体" + "查询数据失败", e);
			return ServiceResult.failure(Constant.ERROR_RETURN_CODE, "查询数据失败", Constant.ERROR_RETURN_MESSAGE);
		}
	}

	/**
	 * 查找文件和文件夹
	 * @param map
	 * @return
	 */
	@RequestMapping(value = "/queryFD.json")
	public ServiceResult queryFD(@RequestBody HashMap<String, Object> map) {
		Integer dirId = (Integer) map.get("dirId");
		
		List<FD> fds = new ArrayList<FD>();
		
		File file = new File();
		file.setDirId(dirId);
		// TODO 未捕获错误
		List<File> fileLise = fileMapper.selectListByPo(file);
		for(File f : fileLise) {
			FD fd = new FD();
			fd.setId(f.getId()+1000);
			fd.setPId(f.getDirId());
			fd.setName(f.getFileName());
			fd.setSize(f.getFileSize());
			fd.setTime(f.getFileUploadTime());
			fd.setFilestatus(f.getFileStatus());
			fd.setIsFile(true);
			fds.add(fd);
		}
		
		
		
		Dir dir = new Dir();
		dir.setDirParentId(dirId);
		// TODO 未捕获错误
		List<Dir> dirList = dirMapper.selectListByPo(dir);
		for(Dir d : dirList) {
			FD fd = new FD();
			fd.setId(d.getId());
			fd.setPId(d.getDirParentId());
			fd.setName(d.getDirName());
			fd.setSize(null);
			fd.setTime(null);
			fd.setFilestatus(null);
			fd.setIsFile(false);
			fd.setPath(d.getDirPath());
			fds.add(fd);
		}
		return ServiceResult.success(fds, "查询文件和文件夹成功");
	}
	
}
